from collections import defaultdict
from typing import Dict, Union

from . import verbose
from .backend import _ip_aliases_check, _subnet_check, _concentration_check
from ..utils import extract_prefix


def __warn():
    return "Not yet implemented"


def raw_aliases_check(crawl_data: dict, threshold: int) -> Dict[str, Union[int, list]]:
    """checks for nodes with too much different addresses"""
    return verbose.raw_aliases_check(crawl_data, threshold)


def raw_roommates_check(crawl_data: dict, threshold: int) -> Dict[str, Union[int, dict]]:
    """checks for IP addresses with too much different nodes"""
    return verbose.raw_roommates_check(crawl_data, threshold)


def raw_ip_aliases_check(crawl_data: dict, threshold: int) -> Dict[str, Union[int, dict]]:
    """checks for IP addresses with too much different nodes"""
    return {"threshold": threshold,
            "results":
                {ip: tuple(res["addresses"])
                 for ip, res in
                 sorted(list(_ip_aliases_check(crawl_data).items()),
                        key=lambda x: len((list(x))[1]["addresses"]), reverse=True)
                 if len(res["addresses"]) >= threshold}}


def raw_subnet_check(crawl_data: dict, threshold: int) -> Dict[str, Union[int, list]]:
    """checks for IP addresses on the same /24 subnet"""
    d = defaultdict(set)
    for key, value in sorted(_subnet_check(crawl_data).items(), key=lambda x: len(x[1]), reverse=True):
        if len(value) >= threshold:
            for (ip, _) in sorted(map(lambda x: (int(x[0].split(".")[-1]), x[1]), value)):
                d[key].add(ip)
    return {"threshold": threshold,
            "results": d}


def raw_concentration_check(crawl_data: dict, threshold: int):
    """checks for grouped node addresses"""
    return {"threshold": threshold, "results": {extract_prefix(x["ids"][0]["a"]["id"], threshold): x["count"] for x in
                                                sorted(_concentration_check(crawl_data, threshold),
                                                       key=lambda x: x["ids"][0]["a"]["id"])}}


def raw_identical_check(crawl_data: dict, threshold: int) -> Dict[str, Union[int, dict]]:
    """checks for nodes sharing the same id"""
    return verbose.raw_identical_check(crawl_data, threshold)
